package git.soulbgm.controller;

import git.soulbgm.common.pojo.TableSupport;
import git.soulbgm.mapper.MessageMapper;
import git.soulbgm.pojo.Message;
import git.soulbgm.pojo.MessageDto;
import git.soulbgm.pojo.MessageParam;
import git.soulbgm.service.MessageService;
import git.soulbgm.utils.DateUtil;
import git.soulbgm.utils.LogUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * 消息控制器
 *
 * @author SoulBGM
 * @date 2021/05/17
 */
@RestController
public class MessageController {

    @Resource
    private MessageMapper mapper;

    @Autowired
    private MessageService messageService;

    private final static LogUtil log = new LogUtil(MessageService.class);

    @GetMapping("list")
    public List<Message> list(MessageParam param) {
        return mapper.list(param);
    }

    @GetMapping("count")
    public Long count(MessageParam param) {
        return mapper.count(param);
    }

    @GetMapping("getCount")
    public int getCount() {
        return mapper.selectCount(null);
    }

    @GetMapping("serviceDataQuery")
    public List<Message> find(MessageDto dto) {
        TableSupport.startPage();
        Long startTime = DateUtil.parse(dto.getStartTime(), DateUtil.FORMAT_YMD).getTime();
        long endTime = DateUtil.parse(dto.getEndTime(), DateUtil.FORMAT_YMD).getTime();
        Example example = new Example(Message.class);
        example.and().andBetween("packageTime", startTime, endTime);
        List<Message> list = mapper.selectByExample(example);
        return list;
    }

    private static class Result {
        private Calendar calendar;
        private Future<Integer> result;

        public Result(Calendar calendar, Future<Integer> result) {
            this.calendar = calendar;
            this.result = result;
        }

        public Calendar getCalendar() {
            return calendar;
        }

        public void setCalendar(Calendar calendar) {
            this.calendar = calendar;
        }

        public Future<Integer> getResult() {
            return result;
        }

        public void setResult(Future<Integer> result) {
            this.result = result;
        }
    }

    @GetMapping("insertDataBulk")
    public String insertDataBulk() throws InterruptedException, ExecutionException {
        long startTime = System.currentTimeMillis();
        List<Calendar> list = DateUtil.getTimeAxis(DateUtil.getCalendar(), DateUtil.MINUTE, 180 * 24 * 60, true);
        int totalNum = 2000;
        int cycleNum = 2000;
        CountDownLatch latch = new CountDownLatch(list.size());
        List<Result> resultList = new ArrayList<>(list.size());
        for (Calendar c : list) {
            Future<Integer> result = messageService.insertList(totalNum, cycleNum, c, latch);
            resultList.add(new Result(c, result));
        }
        latch.await();
        for (Result result : resultList) {
            Calendar c = result.getCalendar();
            Integer totalResult = result.getResult().get();
            log.info("插入 {} 的数据 {}/{}, {}", DateUtil.format(c.getTime(), DateUtil.FORMAT_YMD), totalNum, totalResult, (totalResult == totalNum ? "成功" : "失败"));
        }
        long endTime = System.currentTimeMillis();
        log.info("耗时:{}秒", (endTime - startTime) / 1000);
        return "success";
    }

    @GetMapping("insert")
    public List<Message> insert(int totalNum) {
        Calendar c = DateUtil.getStartCalendar(DateUtil.getCalendar(), DateUtil.DAY);
        Future<List<Message>> future = messageService.insertList(totalNum, c);
        try {
            List<Message> totalResult = future.get();
            log.info("插入 {} 的数据 {}/{}, {}", DateUtil.format(c.getTime(), DateUtil.FORMAT_YMD), totalNum, totalResult, (totalResult.size() == totalNum ? "成功" : "失败"));
            return totalResult;
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
            return null;
        }
    }

    @GetMapping("getIds")
    public List<Message> getIds(String ids) {
        return messageService.findByIds(ids);
    }

}
